-- Lua 格式化插件初始化
-- 尝试加载 cmp 和 luasnip 模块以及配置
local cmp = pRequire("cmp")
local luasnip = pRequire("luasnip")
local cfg = require("guru").config.cmp

-- 如果加载失败或者没有启用配置，则直接返回
if not cmp or not luasnip or not cfg or not cfg.enable then
  return
end

-- 加载自定义的格式化配置
local formatting = require("guru.cmp.format").formatting

-- 键位映射配置
local mapping = {
  -- 触发自动补全的键位
  [cfg.keys.complete] = cmp.mapping(cmp.mapping.complete(), { "i", "c" }),
  -- 取消补全的键位
  [cfg.keys.abort] = cmp.mapping({
    i = cmp.mapping.abort(),
    c = cmp.mapping.close(),
  }),
  -- 确认选中的补全项，如果没有选中，则选中第一个项目
  [cfg.keys.confirm] = cmp.mapping.confirm({
    select = false,
    behavior = cmp.ConfirmBehavior.Replace,
  }),
  -- 文档上下滚动的键位
  [cfg.keys.scroll_doc_up] = cmp.mapping(cmp.mapping.scroll_docs(-4), { "i", "c" }),
  [cfg.keys.scroll_doc_down] = cmp.mapping(cmp.mapping.scroll_docs(4), { "i", "c" }),
  -- 选择上一个/下一个补全项
  [cfg.keys.select_prev_item] = cmp.mapping.select_prev_item(),
  [cfg.keys.select_next_item] = cmp.mapping.select_next_item(),
}

-- 在命令模式下选择下一个/上一个补全项
keymap("c", cfg.keys.select_next_item, "<C-n>", {
  remap = true,
  silent = true,
})
keymap("c", cfg.keys.select_prev_item, "<C-p>", {
  remap = true,
  silent = true,
})

-- 设置 cmp 的全局配置
cmp.setup({
  -- 使用 luasnip 作为代码片段引擎
  snippet = {
    expand = function(args)
      luasnip.lsp_expand(args.body)
    end,
  },
  -- 设置补全窗口和文档窗口有边框
  window = {
    completion = cmp.config.window.bordered(),
    documentation = cmp.config.window.bordered(),
  },
  mapping = mapping, -- 应用上面定义的键位映射
  formatting = formatting, -- 应用自定义的格式化设置
  -- 设置补全源的优先级
  sources = cmp.config.sources({
    {
      name = "nvim_lsp",
      group_index = 1,
      priority = 1000,
    },
    {
      name = "nvim_lsp_signature_help",
      group_index = 1,
      priority = 1000,
    },
    {
      name = "luasnip",
      group_index = 2,
      priority = 1000,
    },
    {
      name = "copilot",
      group_index = 2,
      priority = 750,
    },
    {
      name = "buffer",
      group_index = 3,
      priority = 500,
    },
    {
      name = "path",
      group_index = 3,
      priority = 300,
    },
  }),
})

-- 设置搜索模式下使用 buffer 补全源
cmp.setup.cmdline("/", {
  mapping = cmp.mapping.preset.cmdline(),
  sources = { {
    name = "buffer",
  } },
})

-- 设置命令行模式下使用路径和命令行补全源
cmp.setup.cmdline(":", {
  mapping = cmp.mapping.preset.cmdline(),
  sources = cmp.config.sources({ {
    name = "path",
  } }, { {
    name = "cmdline",
  } }),
})

-- 对特定文件类型（如 markdown 和 help）进行特别设置，禁用文档窗口，设置补全源
cmp.setup.filetype({ "markdown", "help" }, {
  window = {
    documentation = cmp.config.disable,
  },
  sources = { {
    name = "luasnip",
  }, {
    name = "buffer",
  }, {
    name = "path",
  } },
})

-- 加载 luasnip 配置
require("guru.cmp.luasnip")
